namespace MvvmFx.Common.ViewModels.Factories
{
    /// <summary>
    /// The CreateCriteria class is the basic concrete implementation of the
    /// <see cref="ICreateCriteria"/> contract, and is used to pass an Id
    /// to the Create method of an <see cref="IViewModelFactory{T}"/> to
    /// specify how and what it should create.
    /// </summary>
    /// <remarks>
    /// This basic base class just provides a string Key property
    /// by default, but can be derived from by custom implementations to
    /// add custom criteria properties like Ids, Guids, urls or 
    /// model-specific data.
    /// </remarks>
    /// <example>
    /// The following example passes an instance of CreateCriteria to an
    /// <see cref="IViewModelFactory{T}"/> to tell the factory which data
    /// to load from the model.
    /// <code>
    ///   var personFactory = container.Resolve<IViewModelFactory<PersonViewModel>>();
    ///   personViewModel = personFactory.Create(new CreateCriteria { Key = "123" });
    /// </code>
    /// </example>
    public class CreateCriteria : ICreateCriteria
    {
        /// <summary>
        /// The static instance of CreateCriteria that represents an Empty criteria
        /// </summary>
        private static readonly CreateCriteria empty;


        /// <summary>
        /// Initializes the <see cref="CreateCriteria"/> class and creates the
        /// static Empty instance.
        /// </summary>
        static CreateCriteria()
        {
            empty = new CreateCriteria();
        }

        /// <summary>
        /// Gets the Empty instance of CreateCriteria
        /// </summary>
        public static CreateCriteria Empty
        {
            get { return empty; }
        }

        /// <summary>
        /// Returns whether the specified <see cref="ICreateCriteria"/> is
        /// null or empty.
        /// </summary>
        /// <param name="criteria">The criteria to check</param>
        /// <returns>true if null or empty, false otherwise</returns>
        public static bool IsNullOrEmpty(ICreateCriteria criteria)
        {
            return (criteria == null ||
                    criteria.IsEmpty);
        }

        /// <summary>
        /// Gets whether the CreateCritera class is Empty
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                return (this == empty);
            }
        }

        /// <summary>
        /// Gets or sets the string Key value of the <see cref="CreateCriteria"/>
        /// </summary>
        public string Key { get; set; }
    }
}